package pri.zjy.array;

/**
 * @author zhangjy
 * @description 长度最小的子数组
 * @date 2025/6/16 18:03
 */
public class MinSubArrayLen_209 {

    public static void main(String[] args) {
        MinSubArrayLen_209 minSubArrayLen209 = new MinSubArrayLen_209();

        // TODO 前缀和

        int[] nums = {2, 3, 1, 2, 4, 3};
        int target = 7;
        System.out.println(minSubArrayLen209.minSubArrayLen(target, nums));
    }

    /**
     * dmsxl：滑动窗口
     * <p>
     * 思路：left为窗口起点，right为终点
     */
    public int minSubArrayLen2(int s, int[] nums) {
        int left = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            while (sum >= s) {
                result = Math.min(result, right - left + 1);
                sum -= nums[left++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }

    /**
     * 个解：滑动窗口
     */
    public int minSubArrayLen(int target, int[] nums) {
        // 滑动窗口[start,end]
        // while(windowSum>=target)，则一直右移start，并且记录minlength
        // while(windowSum<target)，则一直右移end

        if (nums.length <= 0) return 0;

        int start = 0, end = 0, minLength = Integer.MAX_VALUE, windowSum = nums[end];
        boolean flag = false;
        while (start < nums.length && end < nums.length) {
            while (windowSum >= target) {
                // 先记录最小长度
                minLength = Math.min(minLength, end - start + 1);
                // 再更新窗口值
                windowSum -= nums[start];
                // 最后右移start
                start++;

                flag = true;
            }
            // 若while不判断end，会进入死循环
            while (windowSum < target && end < nums.length) {
                // 先右移end，再更新窗口值
                end++;
                // 保证end不越界
                if (end < nums.length) {
                    windowSum += nums[end];
                }
            }
        }

//        return flag ? minLength : 0;
        // 可能没有任何窗口的元素和=k，那么就不会更新minLength，但此时应该返回0
        return minLength == Integer.MAX_VALUE ? minLength : 0;
    }

}
